package net.avh4.scratch.rpg;

import java.awt.Rectangle;
import java.io.IOException;

/**
 * Generates a landmass by throwing particles from a random point on the
 * map border.  If a thrown particle hits a tile, the particle will
 * "crystalize" and generate a tile at the contact location.
 * @author vonderha
 */
public class CrystalizeWorldMap extends CachedWorldMap {

	public CrystalizeWorldMap() throws IOException {
		super();
		generate();
	}
	
	private void generate() {
		// Seed the crystalization
		setTile(20, 15, 0);
		Rectangle bounds = new Rectangle(20-2, 15-2, 4, 4);
		
		/** The number of particles that have crystalized */
		int crystalized = 0;
		while (crystalized < 250) {
			if (rand.nextBoolean()) {
				// A particle coming horizontally
				int row = rand.nextInt(bounds.height) + bounds.y;
				int i;
				int dir;
				int end;
				if (rand.nextBoolean()) {
					i = (int) Math.floor(bounds.getMinX());
					dir = 1;
					end = (int) Math.ceil(bounds.getMaxX()) - 1;
				} else {
					i = (int) Math.ceil(bounds.getMaxX()) - 1;
					dir = -1;
					end = (int) Math.floor(bounds.getMinX());
				}
				for (; i != end; i += dir) {
					if (getTile(i, row) != -1) {
						setTile(i-dir, row, getTile(i, row));
						crystalized++;
						if (i-dir < Math.floor(bounds.getMinX())) {
							bounds.x--;
							bounds.width++;
						}
						if (i-dir >= Math.ceil(bounds.getMaxX())) {
							bounds.width++;
						}
						break;
					}
				}
			} else {
				// A particle coming vertically
				int col = rand.nextInt(bounds.width) + bounds.x;
				int i;
				int dir;
				int end;
				if (rand.nextBoolean()) {
					i = (int) Math.floor(bounds.getMinY());
					dir = 1;
					end = (int) Math.ceil(bounds.getMaxY()) - 1;
				} else {
					i = (int) Math.ceil(bounds.getMaxY()) - 1;
					dir = -1;
					end = (int) Math.floor(bounds.getMinY());
				}
				for (; i != end; i += dir) {
					if (getTile(col, i) != -1) {
						setTile(col, i-dir, getTile(col, i));
						if (i-dir < Math.floor(bounds.getMinY())) {
							bounds.y--;
							bounds.height++;
						}
						if (i-dir >= Math.ceil(bounds.getMaxY())) {
							bounds.height++;
						}
						crystalized++;
						break;
					}
				}
			}
		}
		
	}
	

}
